package com.zz.client.handle;

import com.zz.common.config.Constants;
import com.zz.common.entity.ProtocolInfo;
import com.zz.common.enums.MessageType;
import com.zz.common.handle.executor.MessageExecutor;
import com.zz.common.handle.executor.MessageExecutorFactory;
import com.zz.common.utils.ObjectUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.EmptyArrays;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.Optional;

/**
 * 本地处理器
 *
 * @author zz
 */
@Slf4j
public class LocalHandler  extends SimpleChannelInboundHandler<byte[]> {

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext context) throws Exception {
        Channel salveChannel = context.channel().attr(Constants.Attributes.SERVER_CHANNEL).get();
        ObjectUtil.setReadable(salveChannel, context.channel().isWritable());
        super.channelWritabilityChanged(context);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext context, byte[] bytes) throws Exception {
        Channel salaveChannel = context.channel().attr(Constants.Attributes.SERVER_CHANNEL).get();
        if (Objects.isNull(salaveChannel)) {
            context.close();
            return;
        }
        sendMessage(context, bytes, salaveChannel);
    }

    private static void sendMessage(ChannelHandlerContext context, byte[] bytes, Channel salaveChannel) {
        // 构建消息实体
        ProtocolInfo protocolInfo = ProtocolInfo.builder()
                .serverChannel(salaveChannel).context(context).type(MessageType.TYPE_TRANSFER).data(bytes).build();

        MessageExecutor executor = MessageExecutorFactory.getMessageExecutor(MessageType.TYPE_TRANSFER);
        if (Objects.isNull(executor)) {
            log.info("错误！找不到对应的消息处理器！messageType:{}", MessageType.TYPE_TRANSFER);
            return;
        }
        executor.execute(protocolInfo);
    }

    /**
     * 连接断开
     */
    @Override
    public void channelInactive(ChannelHandlerContext context) throws Exception {
        Channel salveChannel = context.channel().attr(Constants.Attributes.SERVER_CHANNEL).get();
        if (ObjectUtil.isNotNull(salveChannel) && salveChannel.isActive()) {
            sendMessage(context, EmptyArrays.EMPTY_BYTES, salveChannel);
        }
    }
}
